package com.qcby.demo.proxyaop.proxy.jdk;

import com.qcby.demo.proxyaop.proxy.star.IAdvertisement;
import com.qcby.demo.proxyaop.proxy.star.JiaLing;
import sun.misc.ProxyGenerator;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Proxy;

/**
 * @className: JdkDynamicProxy
 * @description:jdk动态代理
 * @author: lxt
 * @create: 2021-05-12 15:34
 **/
public class JdkDynamicProxy {


    /**
     * 字节码生成技术
     *
     *   代理对象对应的class文件在哪？
     *
     *
     *   idea => 看到class文件中的java代码 => idea内置了 反编译功能 => class文件 会反编译成java代码
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
        // 创建目标对象
        JiaLing jiaLing = new JiaLing();
        // 绑定贾玲和广告代理类的关系
        AdvertisementHandler advertisementHandler = new AdvertisementHandler(jiaLing);
        /**
         *
                 @SuppressWarnings("unchecked")
                 protected T newInstance(MapperProxy<T> mapperProxy) {
                        return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader()
                         , new Class[] { mapperInterface }
                         , mapperProxy
                    );
                 }
         */
        //因为JDK为我们生成的动态代理对象也会去实现真实对象实现了的所有的接口
        //所以此处我们可以直接使用Advertisement接口来接受JDK动态代理生成的代理对象【经纪人】
        /**
         * 1、ClassLoader loader  =>  自己的类加载 ：对象.getClass().getClassLoader()
         * 2、Class<?>[] interfaces, =>  实现的所有接口： 对象.getClass().getInterfaces()
         * 3、InvocationHandler h  => 对应的代理逻辑类 ：     定义了即将生成的代理类的业务逻辑。
         */
        IAdvertisement advertisement = (IAdvertisement) Proxy.newProxyInstance(
                jiaLing.getClass().getClassLoader()
                , jiaLing.getClass().getInterfaces()
                ,advertisementHandler
        );
//        //通过反编译工具可以查看源代码
//        byte[] bytes= ProxyGenerator.generateProxyClass("$Proxy0",new Class[]{IAdvertisement.class});
//         // idea 打开字节码文件，可查看动态生成的代理类
//        String dir = "/Users/lxt/Documents/git/gitlab/2021/demo_2021/proxyaopdemo/class/";
//        File file = new File(dir);
//        if(!file.exists()){
//            file.mkdirs();
//        }
//         FileOutputStream os=new FileOutputStream(dir+"$Proxy0.class");
//         os.write(bytes);
//         os.close();
        //执行代理对象【经纪人】的display（）方法
        // super.h.invoke(this, m4, (Object[])null);
//        advertisement.display();
//        advertisement.displayRe();
        advertisement.tv();
    }

//    public static void main(String[] args) throws IOException {
//        JiaLing jiaLing = new JiaLing();
//        // 绑定贾玲和广告代理类的关系
//        TvHandler tvHandler = new TvHandler(jiaLing);
//        //因为JDK为我们生成的动态代理
//        // 对象也会去实现真实对象实现了的所有的接口
//        //所以此处我们可以直接使用Advertisement接口来接受JDK动态代理生成的代理对象【经纪人】
//        IAdvertisement advertisement = (IAdvertisement) Proxy.newProxyInstance(jiaLing.getClass().getClassLoader()
//                , jiaLing.getClass().getInterfaces(),tvHandler);
//
//        //通过反编译工具可以查看源代码
//         byte[]bytes= ProxyGenerator.generateProxyClass("$Proxy0",new Class[]{IAdvertisement.class});
//         // idea 打开字节码文件，可查看动态生成的代理类
//        String dir = "D:/proxydemo/jdk/";
//        File file = new File(dir);
//        if(!file.exists()){
//            file.mkdirs();
//        }
//         FileOutputStream os=new FileOutputStream(dir+"$Proxy0.class");
//         os.write(bytes);
//         os.close();
//
//        //执行代理对象【经纪人】的display（）方法
//        advertisement.display();
//    }
}
